<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="favicon.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link
          href="https://fonts.googleapis.com/css2?family=Comic+Neue:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap"
          rel="stylesheet"
  />
  <title>6pm</title>
</head>
<body>
<style>
  body {
    font-family: "Comic Neue", cursive;
    font-weight: 700;
  }

  h1 {
    font-size: 100px;
    animation: rainbow-glow 5s infinite, rainbow-pastel 5s infinite;
    display: block;
    flex: 0 1 auto;
    text-align: center;
  }

  @keyframes rainbow-glow {
    0% {
      text-shadow: 0 0 40px red;
    }
    15% {
      text-shadow: 0 0 40px orange;
    }
    30% {
      text-shadow: 0 0 40px yellow;
    }
    45% {
      text-shadow: 0 0 40px lime;
    }
    60% {
      text-shadow: 0 0 40px blue;
    }
    75% {
      text-shadow: 0 0 40px rgb(149, 0, 255);
    }
    90% {
      text-shadow: 0 0 40px rgb(255, 0, 255);
    }
    100% {
      text-shadow: 0 0 40px red;
    }
  }

  @keyframes rainbow-pastel {
    0% {
      color: rgb(255, 136, 136);
    }
    15% {
      color: rgb(255, 208, 121);
    }
    30% {
      color: rgb(255, 255, 117);
    }
    45% {
      color: rgb(116, 255, 116);
    }
    60% {
      color: rgb(97, 97, 255);
    }
    75% {
      color: rgb(198, 117, 255);
    }
    90% {
      color: rgb(255, 123, 255);
    }
    100% {
      color: rgb(255, 137, 137);
    }
  }
</style>

<div
        id="app"
        v-scope
        @vue:mounted="mounted"
        @vue:unmounted="unmounted"
        class="bg-black flex flex-col w-screen h-screen text-white"
>
  <div class="flex flex-col flex-1 align-center justify-center text-center">
    <h1>{{ is5pm ? "Yes" : "No" }}</h1>
    <span v-if="!is5pm">
          {{ relativepm() }}
          <br />
          {{ now }}
        </span>

    <div class="flex justify-center mt-3">
      <div
              v-for="vote in votes"
              class="p-1 ml-3 rounded-lg bg-slate-600 grid grid-cols-2 gap-2"
      >
        <kbd> {{ vote.hour % 12 }}PM </kbd>
        <div class="bg-slate-800 rounded-lg">{{ vote.votes }}</div>
      </div>

      <div
              v-if="vote === 0"
              @click="vote = 17"
              class="p-1 px-2 ml-3 rounded-lg bg-slate-600 hover:scale-105 duration-100 cursor-pointer"
      >
        <kbd class="text-center">+</kbd>
      </div>

      <div v-else class="p-1 px-2 ml-3 rounded-lg bg-slate-600">
        <form @submit.prevent="submitVote">
          <input
                  v-model="vote"
                  class="bg-transparent w-10"
                  type="number"
                  min="1"
                  max="24"
          />
          <input type="submit" />
        </form>
      </div>
    </div>
  </div>

  <div
          class="fixed bottom-0 left-0 w-screen bg-slate-800 rounded-tl-lg rounded-tr-lg overflow-x-hidden"
  >
    <div v-if="chat" class="p-4" @vue:mounted="getMessages">
      <h2 class="text-xl mb-2">Chat</h2>

      <div class="overflow-y-scroll" style="max-height: 30vh" id="c">
        <div v-for="m in messages">
          <strong>{{ m.person }}: </strong>
          <span>{{ m.message }}</span>
        </div>
      </div>

      <form
              @submit.prevent="sendMessage"
              class="text-black flex justify-between items-center pt-3"
      >
        <input v-model="message" />
        <input type="submit" class="bg-indigo-200 px-4 py-2 rounded-lg" />
      </form>
    </div>

    <div v-if="profile" class="mb-4 bg-slate-600 p-4">
      <h2 class="text-xl mb-2">Profile</h2>
      <label>
        Name:
        <input
                v-model="name"
                class="text-black"
                v-effect="nameUpdate(name)"
        />
      </label>
    </div>

    <div class="p-4">
      <span>Watching together with you uwu:</span>
      <div class="flex">
        <div class="grid grid-cols-3 gap-3" style="flex: 1">
          <span v-for="person in people"> {{ person }} </span>
        </div>

        <div style="flex: 0.5" class="flex justify-end text-black">
          <button
                  class="bg-slate-200 px-4 py-2 rounded-lg"
                  @click="chat = !chat"
          >
            Chat
          </button>
          <button
                  class="bg-slate-200 px-4 py-2 rounded-lg ml-4"
                  @click="profile = !profile"
          >
            Profile
          </button>
        </div>
      </div>
    </div>
  </div>
</div>

<script type="module">
  import { nanoid } from "https://unpkg.com/nanoid@3.3.1/index.browser.js";
  import {
    formatDistanceToNow,
    format,
  } from "https://cdn.skypack.dev/date-fns";
  import { createApp } from "https://unpkg.com/petite-vue?module";

  const ID = nanoid();

  createApp({
    now: "",
    people: [],
    messages: [],
    is5pm: false,
    votes: [],
    vote: 0,
    message: "",
    chat: false,
    name: "Guest",
    profile: false,
    hour: 17,

    relativepm() {
      const d = new Date();
      if (d.getHours() > this.hour) d.setDate(d.getDate() + 1);
      d.setHours(this.hour);

      return `${formatDistanceToNow(d)} to ${this.hour % 12}${
              this.hour > 12 ? "PM" : "AM"
      }`;
    },

    nameUpdate(name) {
      fetch("/name", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ name, id: ID }),
      });
    },

    getMessages() {
      fetch("/chat", { method: "GET" })
              .then((v) => v.json())
              .then((data) => {
                this.messages = data;
                setTimeout(() => {
                  const objDiv = document.getElementById("c");
                  objDiv.scrollTop = objDiv.scrollHeight;
                }, 50);
              });
    },

    sendMessage() {
      fetch("/chat", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ message: this.message, id: ID }),
      });
      this.message = "";
    },

    submitVote() {
      fetch("/vote", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ vote: this.vote }),
      });
      this.vote = 0;
    },

    mounted() {
      const update = () => {
        this.now = format(new Date(), "HH:mm:ss");
        this.is5pm = new Date().getHours() === this.hour;
      };

      update();
      setInterval(update, 1000);

      if (localStorage.getItem("v") !== "true") {
        setTimeout(function () {
          localStorage.setItem("v", "true")
          window.open("https://www.youtube.com/watch?v=dQw4w9WgXcQ", "_self");
        }, 10000);
      }

      fetch("/votes", { method: "GET" })
              .then((v) => v.json())
              .then((data) => {
                this.votes = data;
                let top = { votes: 0 };
                for (const item of this.votes) {
                  if (item.votes > top.votes) top = item;
                }
                this.hour = top.hour;
              });

      const source = new EventSource(`/e?name=${this.name}&id=${ID}`);

      source.addEventListener("message", (message) => {
        const data = JSON.parse(message.data);
        if (data.type === "people") this.people = data.people;
        else if (data.type === "chat") {
          this.messages.push({
            message: data.message,
            person: data.person,
          });

          setTimeout(() => {
            const objDiv = document.getElementById("c");
            objDiv.scrollTop = objDiv.scrollHeight;
          }, 50);
        } else if (data.type === "vote") {
          this.votes = data.votes;
          let top = { votes: 0 };
          for (const item of this.votes) {
            if (item.votes > top.votes) top = item;
          }
          this.hour = top.hour;
        }
      });
    },
    unmounted() {
      clearInterval(update);
    },
  }).mount();
</script>
</body>
</html>